SDLTest_CompareSurfaces: Decode pixels correctly on big-endian platforms #8317
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously, if acting on a surface with less than 32 bits per pixel, this code was placing the pixel value from the surface in the first few bytes of the Uint32 to be decoded, and unrelated data from a subsequent pixel in the remaining bytes.
Because SDL_GetRGBA takes the bits to be decoded from the least-significant bits of the given value, ignoring the higher-order bits if any, this happened to be correct on little-endian platforms, where the first few bytes store the least-significant bits of an integer.
However, it was incorrect on big-endian, where the first few bytes are the most-significant bits of an integer.
The previous implementation also assumed that unaligned access to a 32-bit quantity is possible, which is not the case on all CPUs (but happens to be true on x86).
These issues were not discovered until now because SDLTest_CompareSurfaces() is only used in testautomation, which until recently was not being run routinely at build-time, because it contained other assumptions that can fail in an autobuilder or CI environment.
Resolves: #8315
I think this would also be worthwhile to cherry-pick to SDL 2 and sdl2-compat, if it's applicable there.
It might even be a good idea to have a slow, simple but fully-correct
SDL_ReadSurfacePixel(SDL_Surface *, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
as public API, but I'd prefer to fix the test with this private implementation before promoting it into public API, because I'd prefer not to have API design considerations delay the fix.